package com.code.translate.plugins;

import com.alibaba.fastjson.JSON;
import com.code.translate.function.ImageTranslatePlugin;
import com.code.translate.utils.HttpUtils;
import com.code.translate.utils.JsonpathUtils;
import com.code.translate.utils.MD5Utils;
import com.code.translate.utils.PatternUtils;
import org.springframework.http.*;

import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ggh
 * @date 2022/7/20
 * <p>
 * 搜狗翻译
 */
public class SougouTranslatePlugin extends ImageTranslatePlugin {
    private static final String indexUrl = "https://fanyi.sogou.com/text";
    private static final String translateUrl = "https://fanyi.sogou.com/api/transpc/text/result";
    private static final String originUrl = "https://fanyi.sogou.com";

    // 图片翻译
    private static final String imageIndexUrl = "https://fanyi.sogou.com/picture";
    private static final String imageTranslateUrl = "https://fanyi.sogou.com/api/transpc/picture/upload";

    private static SougouTranslatePlugin singleton = new SougouTranslatePlugin();

    private SougouTranslatePlugin() {
    }

    public static SougouTranslatePlugin getSingleton() {
        return singleton;
    }

    @Override
    protected Map<String, Object> prepare() throws Exception {
        RequestEntity requestEntity = new RequestEntity(HttpMethod.GET, URI.create(indexUrl));

        ResponseEntity<String> responseEntity = HttpUtils.reqEntity(requestEntity);
        Map<String, Object> params = new HashMap<>();
        StringBuilder stringBuilder = new StringBuilder();
        for (String setCookies : responseEntity.getHeaders().get("Set-Cookie")) {
            String[] cookies = setCookies.split(";");
            stringBuilder.append(cookies[0]);
            stringBuilder.append("; ");
        }

        params.put("cookie", stringBuilder.toString());
        params.put("uuid", responseEntity.getHeaders().get("UUID").get(0));
        params.put("secretCode", PatternUtils.regex(responseEntity.getBody(), "\"secretCode\":(\\w+),"));
        return params;
    }

    @Override
    protected String doTranslate(String text, Map<String, Object> params) throws Exception {
        Map<String, Object> requestParams = structParams(text, params);
        Map<String, String> requestHeads = new HashMap<>(3);
        requestHeads.put("Referer", indexUrl);
        requestHeads.put("Origin", originUrl);
        requestHeads.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
        requestHeads.put("Cookie", (String) params.get("cookie"));

        String result = HttpUtils.req(translateUrl, HttpMethod.POST, requestHeads, requestParams);
        return JsonpathUtils.read(result, "$.data[*].dit");
    }

    private static Map<String, Object> structParams(String text, Map<String, Object> needParams) throws Exception {
        Map<String, Object> params = new HashMap<>(9);

        params.put("client", "pc");
        params.put("exchange", "false");
        params.put("fr", "browser_pc");
        params.put("from", "en");
        params.put("to", "zh-CHS");
        params.put("needQc", "0");
        params.put("text", text);

        String sign = MD5Utils.md5Hex((params.get("from").toString() + params.get("to").toString() + text + needParams.get("secretCode")).getBytes());
        params.put("uuid", needParams.get("uuid"));
        params.put("s", sign);

        return params;
    }

    @Override
    protected Map<String, Object> prepareImage() throws Exception {
        RequestEntity requestEntity = new RequestEntity(HttpMethod.GET, URI.create(indexUrl));

        ResponseEntity<String> responseEntity = HttpUtils.reqEntity(requestEntity);
        Map<String, Object> params = new HashMap<>();
        StringBuilder stringBuilder = new StringBuilder();
        for (String setCookies : responseEntity.getHeaders().get("Set-Cookie")) {
            String[] cookies = setCookies.split(";");
            stringBuilder.append(cookies[0]);
            stringBuilder.append("; ");
        }

        params.put("cookie", stringBuilder.toString());
        params.put("uuid", responseEntity.getHeaders().get("UUID").get(0));
        return params;
    }

    @Override
    protected String doTranslateImage(File image, Map<String, Object> params) throws Exception {
        Map<String, Object> requestParams = structImageParams(image, params);

        Map<String, String> requestHeads = new HashMap<>(3);
        requestHeads.put("Referer", imageIndexUrl);
        requestHeads.put("Origin", originUrl);
        requestHeads.put("Cookie", (String) params.get("cookie"));
        requestHeads.put(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE);
        String result = HttpUtils.req(imageTranslateUrl, HttpMethod.POST, requestHeads, requestParams);

        if (result != null && result.contains("status\":0")) {
            String content = JsonpathUtils.read(result, "$.data.result[*].trans_content");
            return content;
        }
        return null;
    }

    @Override
    public String doTranslateImageByStream(InputStream inputStream, Map<String, Object> params) throws Exception {
        Map<String, Object> requestParams = structImageParams(inputStream, params);

        Map<String, String> requestHeads = new HashMap<>(3);
        requestHeads.put("Referer", imageIndexUrl);
        requestHeads.put("Origin", originUrl);
        requestHeads.put("Cookie", (String) params.get("cookie"));
        requestHeads.put(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE);
        String result = HttpUtils.req(imageTranslateUrl, HttpMethod.POST, requestHeads, requestParams);

        if (result != null && result.contains("status\":0")) {
            String content = JsonpathUtils.read(result, "$.data.result[*].trans_content");
            return content;
        }
        return null;
    }

    private static Map<String, Object> structImageParams(Object image, Map<String, Object> needParams) throws Exception {
        Map<String, Object> params = new HashMap<>(3);
        Map<String, Object> extraDatas = new HashMap<>(3);
        extraDatas.put("from", "en");
        extraDatas.put("to", "zh-CHS");
        extraDatas.put("imageName", "text.png");

        params.put("extraData", JSON.toJSONString(extraDatas));
        params.put("fuuid", needParams.get("uuid"));
        params.put("fileData", image);

        return params;
    }

}
